/**
 * 
 */
package org.youisoft.summer.evaluator.function.control;

import java.security.PrivilegedAction;
import java.util.concurrent.atomic.AtomicInteger;

import org.youisoft.summer.evaluator.InvokeException;
import org.youisoft.summer.evaluator.context.CalContext;
import org.youisoft.summer.evaluator.function.AbstractFunction;
import org.youisoft.summer.evaluator.operator.Operator;
import org.youisoft.summer.evaluator.operator.base.ClosureOperator;
import org.youisoft.summer.evaluator.operator.base.NumberOperator;

/**
 * @author zijiang.jl
 *
 */
public class ThreadFunction extends AbstractFunction{
	
	@Override
	protected boolean checkOperator(int index, Operator<?> operator) {
		if(index==0&&ClosureOperator.class.isAssignableFrom(operator.getClass())) return true;
		if(index==1&&NumberOperator.class.isAssignableFrom(operator.getClass())) return true;
		return false;
	}

	@Override
	public <C,R,P> Operator<?> doInvoke(final CalContext<C,R,P> context,Operator<?>... operator) throws InvokeException{
		final ClosureOperator call=ClosureOperator.class.cast(operator[0]);
		final int cnt=NumberOperator.class.cast(operator[1]).value().intValue();
		logger.warn("start new thread........");
		final AtomicInteger ai=new AtomicInteger(0);
		while(ai.incrementAndGet()<=cnt){
			java.security.AccessController.doPrivileged(new PrivilegedAction<Operator<?>>(){
				@Override
				public Operator<?> run() {
					logger.warn("begin closure thread:"+ai.get());
					new Thread("Closure thread:"+ai.get()){
						@Override
						public void run() {
							try {
								call.execute(context.clone());
							} catch (java.lang.Throwable t) {
								logger.error(t.getMessage());
								logger.debug(t);
							}
						}
						
					}.start();
					return Operator.nullInstance;
				}
				
			});	
		}
		return Operator.nullInstance;
	}
	

	
	
	@Override
	protected int minOperatorCount() {
		return 2;
	}
	
}
